package org.netty.message.gper.code;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

import org.netty.message.gper.entity.GpHeader;
import org.netty.message.gper.entity.GpMessageRecord;
import org.netty.message.gper.entity.User;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;

public class GpDecode extends LengthFieldBasedFrameDecoder {

	public GpDecode() {
		// [length][headerLength][headerData][body]
		super(Integer.MAX_VALUE, 0, 4, 0, 4);
		// TODO Auto-generated constructor stub
	}

	@Override
	protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
		// TODO Auto-generated method stub
		ByteBuf frame = (ByteBuf) super.decode(ctx, in);
		if (null == frame) {
			return null;
		}
		ByteBuffer buffer = frame.nioBuffer();
		return GpDecode.decode(buffer);
	}

	private static GpMessageRecord decode(ByteBuffer buffer) {
		// TODO Auto-generated method stub
		// [headerLength][headerData][body] 的长度
		int length = buffer.limit();
		// 头的长度
		int headerLength = buffer.getInt();
		// 头的字节的数据
		byte[] headerData = new byte[headerLength]; 
		buffer.get(headerData);
		 
		GpMessageRecord gpMessageRecord = new GpMessageRecord();
		gpMessageRecord.setLength(length);
		// 反序列化头数据得到头对象
		GpHeader header = deserializable(GpHeader.class,headerData);
		header.setHeaderLength(headerLength);
		
		gpMessageRecord.setHeader(header);
		// 反序列化body对象
		int bodyLength = length - 4 - headerLength;
		byte[] bodyData = null;
		if(bodyLength>0) {
			bodyData = new byte[bodyLength];
			buffer.get(bodyData);
		}  
		gpMessageRecord.setBody(deserializable(User.class,bodyData));
		
		return gpMessageRecord;  
 

	}

	private static <T> T deserializable(Class<T> clazz, byte[] data) {
		ObjectInputStream ois = null;
		try {
			ois = new ObjectInputStream(new ByteArrayInputStream(data));
			return (T) ois.readObject();
		} catch (IOException | ClassNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}

}
